package com.example.demo.mq.rabbitMq;

import com.example.demo.dto.UserDto;
import com.example.demo.util.SerializeUtil;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 简单模式
 * 消息消费者
 */
@Component
@RabbitListener(queues = "my_queue")//监听的队列名称
//@RabbitListener(queuesToDeclare = @Queue("simple_queue"))  //如果simple_queue队列不存在，则创建simple_queue队列。默认队列是持久化，非独占式的
public class SimpleConsumer {

    //消费者如果监听到消息队列有消息传入，则会自动消费
    @RabbitHandler
    public void receive(Map message) {
        System.out.println("简单模式 -> 消费者收到map类型消息  : " + message.toString());
    }


    @RabbitHandler
    public void receive(byte[] userDto) {
        System.out.println("简单模式 -> 消费者收到Object类型消息  : " + unSerializeObjOrString(userDto).toString());
    }

    @RabbitHandler
    public void receive2(String message) {
        System.out.println("简单模式 -> 消费者收到string类型消息  : " + message.toString());
    }

    /**
     * * 反序列化byte[]为object或者String。</br>
     * * 注意：如果是Object序列化后的byte[],仅适用jdk自带的序列化</br>
     * * 使用本方法能避免直接反序列化，通过异常判断是String还是Object（只有巧合的走异常流程）。
     */
    private Object unSerializeObjOrString(byte[] bytes) {
        // 不足6位，直接认为是字符串，,经测试单个字符序列化后的byte[]也有8位
        if (bytes.length < 6) {
            return SerializeUtil.Byte2String(bytes);
        }
        String protocol = Integer.toHexString(bytes[0] & 0x000000ff) + Integer.toHexString(bytes[1] & 0x000000ff);
        // 如果是jdk序列化后的
        if ("ACED".equals(protocol.toUpperCase())) {
            Object obj = SerializeUtil.unserializeObj(bytes);
            if (obj != null) {
                return obj;
            }
            // 如果是巧合，则返回的是null
            else {
                return SerializeUtil.Byte2String(bytes);
            }
        }
        // 如果是字符串的byte[]字节形式
        return SerializeUtil.Byte2String(bytes);
    }
}
